#!/bin/sh

# This hook script prevents the user from pushing to the project's Git repo if
# any of the new commits' OpenPGP signatures cannot be verified, if a commit is
# signed with an unauthorized key, or if the channel news file is malformed
# (which would break the build).

# Called by "git push" after it has checked the remote status, but before
# anything has been pushed.  If this script exits with a non-zero status nothing
# will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local sha1> <remote ref> <remote sha1>

# This is the "empty hash" used by Git when pushing a branch deletion.
z40=0000000000000000000000000000000000000000

perform_checks() {
	set -e
	guix git authenticate
	exec make check-channel-news
	exit 127
}

main() {
while read local_ref local_hash remote_ref remote_hash
do
	# When deleting a remote branch, no commits are pushed to the remote,
	# and thus there are no signatures or news updates to be verified.
        if [ "$local_hash" != $z40 ]
        then
                # Skip the hook when performing a pull-request...
                case "$remote_ref" in
                    refs/for/*)
                        exit 0
                        ;;
                    # ... or when pushing a new PGP key to the keyring branch,
                    # as this branch doesn't share ancestry with the master
                    # branch and fails the 'guix git authenticate' check.
                    refs/heads/keyring)
                        exit 0
                        ;;
                esac

		# Only perform checks when pushing to upstream.
		case "$2" in
	            *savannah.gnu.org*)
			printf "ERROR: The repositories on Savannah are read-only mirrors of our repos at <https://codeberg.org/guix>.\n" 1>&2
			exit 1
			;;
		    *.gnu.org*)
			perform_checks
			;;
                    # HTTPS Git remote.
		    *codeberg.org/guix/*)
			perform_checks
			;;
		    # SSH Git remote.
		    *codeberg.org:guix/*)
			perform_checks
			;;
		    *)
			exit 0
			;;
		esac
	fi
done

exit 0
}

main "$@"
